package com.ocom.payconfig.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ocom.common.entity.payconfig.EntityFeeItemPlan;
import com.ocom.common.entity.payconfig.FeeData;
import com.ocom.common.entity.payconfig.FeeItem;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.utils.StringUtil;
import com.ocom.common.vo.payconfig.FeeItemListVo;
import com.ocom.common.vo.payconfig.FeeItemXMVo;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payconfig.dao.IDaoFeeItem;
import com.ocom.payconfig.service.FeeDataService;
import com.ocom.payconfig.service.FeeItemPlanService;
import com.ocom.payconfig.service.FeeItemService;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 缴费项目 服务实现类
 * </p>
 *
 * @author junShu
 * @since 2023-08-18
 */
@Service
public class FeeItemServiceImpl extends JoinServiceImpl<IDaoFeeItem, FeeItem> implements FeeItemService {
    @Resource
    private FeeDataService feeDataService;

    @Autowired
    FeeItemPlanService feeItemPlanService;

    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    public Result feeItemList(Long comId, FeeItemListVo request) {
        QueryWrapper<FeeItem> query = Wrappers.query();
        query.select("item_id", "item_name", "account_id", "status", "remark", "dept_id", "DATE_FORMAT(start_date, '%Y-%m-%d') as startDate", "DATE_FORMAT(stop_date, '%Y-%m-%d') as stopDate", "close_time", "pause_time");
        query.eq("com_id", request.getComId());
        if (request.getBeginDate() != null) {
            query.ge("start_date", request.getBeginDate());
        }
        if (request.getEndDate() != null) {
            query.le("start_date", request.getEndDate());
        }
        if (StringUtil.isNotEmpty(request.getStrStatus())) {
            if (request.getStrStatus().contains(",")) {
                String[] strStatus = request.getStrStatus().split(",");
                query.inSql("status", request.getStrStatus());
            } else {
                query.eq("status", request.getStrStatus());
            }
        }
        if (StringUtil.isNotEmpty(request.getItemName())) {
            query.like("item_name", request.getItemName());
        }
        if (request.getFeeItemId() != 0) {
            query.eq("item_id", request.getFeeItemId());
        }
        if (request.getAccountId() != 0) {
            query.eq("account_id", request.getAccountId());
        }
        if (request.getDeptId() != 0) {
            query.eq("dept_id", request.getDeptId());
        }
        if (request.getPage() == null || request.getSize() == null || request.getPage() == -1 || request.getSize() == -1) {
            request.setPage(1);
            request.setSize(500);
        }
        query.orderByDesc("item_id");
        List<FeeItem> listFeeItem = this.list(query);
        PageHelper.startPage(request.getPage(), request.getSize());
        PageInfo<FeeItem> pageInfo = new PageInfo<FeeItem>(listFeeItem);
        StringBuffer strItemID = new StringBuffer();
        if (listFeeItem != null) {
            for (int i = 0; i < listFeeItem.size(); i++) {
                FeeItem item = listFeeItem.get(i);
                strItemID.append(item.getItemId());
                if (i < listFeeItem.size() - 1) {
                    strItemID.append(",");
                }
            }
        }
        List<Map<String, Object>> mapSumFee = null;
        if (StringUtil.isNotEmpty(strItemID)) {
            mapSumFee = feeDataService.getSumFeeData(request.getComId(), strItemID.toString());
        }
        if (mapSumFee != null && mapSumFee.size() > 0) {
            for (FeeItem item : listFeeItem) {
                for (Map<String, Object> map : mapSumFee) {
                    if(item.getItemId() == Integer.parseInt(String.valueOf(map.get("itemId"))) ){
//                        System.out.println("getItemId====="+item.getItemId());
//                        System.out.println("planAmount====="+map.get("planAmount"));
                        item.setPlanAmount(Integer.parseInt(String.valueOf(map.get("planAmount"))));
                        item.setPlanNumber(Integer.parseInt(String.valueOf(map.get("planNumber"))));
                        item.setCompleteAmount(Integer.parseInt(String.valueOf(map.get("completeAmount"))));
                        item.setCompleteNumber(Integer.parseInt(String.valueOf(map.get("completeNumber"))));
                        item.setRefundAmount(Integer.parseInt(String.valueOf(map.get("refundAmount"))));
                        item.setRefundNumber(Integer.parseInt(String.valueOf(map.get("refundNumber"))));
                    }
                }
            }
        }
        HashMap<String, Object> mapFeeItem = new HashMap<>();
        mapFeeItem.put("list", listFeeItem);
//        mapFeeItem.put("statistic", mapSumFee);
        mapFeeItem.put("total", pageInfo.getTotal());
        PageHelper.clearPage();
        return ResultUtil.success(mapFeeItem);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    public boolean existName(Long comId, String strName) {
        QueryWrapper query = Wrappers.query();
        query.select("item_id");
        query.eq("com_id", comId);
        query.eq("item_name", strName);
        query.last("Limit 1");
        FeeItem feeItem = this.getOne(query);
        if (feeItem == null) {
            return false;
        }
        return true;
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    public Result addSave(Long comId, FeeItem request) {
        if (existName(request.getComId(), request.getItemName())) {
            return ResultUtil.error(ResultEnum.Err_4132);
        }
        boolean ret = save(request);
        return ResultUtil.success(ret);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    public Result editSave(Long comId, FeeItem feeItem) {
        boolean ret = updateById(feeItem);
        return ResultUtil.success(ret);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    public Result startFeeItem(Long comId, FeeItem feeItem) {
        feeItem.setStatus(2);
        boolean ret = updateById(feeItem);
        return ResultUtil.success(ret);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    public Result pauseFeeItem(Long comId, FeeItem feeItem) {
        feeItem.setStatus(3);
        feeItem.setPauseTime(new Date());
        boolean ret = updateById(feeItem);
        return ResultUtil.success(ret);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    public Result closeFeeItem(Long comId, FeeItem feeItem) {
        feeItem.setStatus(5);
        feeItem.setCloseTime(new Date());
        boolean ret = updateById(feeItem);
        return ResultUtil.success(ret);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId", isMaster = MasterSlaveEnum.MASTER)
    public FeeItem getByStatus(Long comId, int feeItemId) {
        QueryWrapper query = Wrappers.query();
        query.select("item_id");
        query.eq("com_id", comId);
        query.eq("status", 1);
        FeeItem item = this.getById(feeItemId);
        return item;
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    public Result feeItemListByWay(Long comId, FeeItemListVo request) {
        QueryWrapper query = Wrappers.query();
        query.select("account_id AS accountId");
        query.eq("com_id", request.getComId());
        if (request.getFeeItemId() != 0) {
            query.eq("item_id", request.getFeeItemId());
        }
        query.last("Limit 1");
        FeeItem item = this.getOne(query);
        if(item == null){
            return new Result(401,"未找到该项目信息:" + request.getFeeItemId() , "");
        }
        return ResultUtil.success(item.getAccountId());
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    public FeeItem findByFeeDataId(Long comId, Integer feeDataId) {
        QueryWrapper<FeeData> feeDataQueryWrapper = Wrappers.query();
        feeDataQueryWrapper.eq("id", feeDataId);
        feeDataQueryWrapper.eq("com_id", comId);
        feeDataQueryWrapper.last("limit 1");
        FeeData feeData = feeDataService.getOne(feeDataQueryWrapper);

        if (null == feeData) {
            return null;
        }

        QueryWrapper<FeeItem> queryWrapper = Wrappers.query();
        queryWrapper.eq("item_id", feeData.getItemId());
        queryWrapper.eq("com_id", comId);
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.SLAVE)
    public Page<FeeItemXMVo> feeItemListXM(Long companyId, FeeItemListVo request) {
        JoinLambdaWrapper<FeeItem> queryWrapper = new JoinLambdaWrapper<>(FeeItem.class);
        queryWrapper.select(FeeItem::getItemId,FeeItem::getComId, FeeItem::getItemName, FeeItem::getAccountId,
                FeeItem::getStatus, FeeItem::getRemark, FeeItem::getDeptId, FeeItem::getCloseTime, FeeItem::getPauseTime, FeeItem::getStartDate,
                FeeItem::getStopDate);
        queryWrapper.eq(FeeItem::getComId, request.getComId());
        if (request.getBeginDate() != null) {
            queryWrapper.ge(FeeItem::getStartDate, request.getBeginDate());
        }
        if (request.getEndDate() != null) {
            queryWrapper.le(FeeItem::getStartDate, request.getEndDate());
        }
        if (StringUtil.isNotEmpty(request.getStrStatus())) {
            if (request.getStrStatus().contains(",")) {
                String[] strStatus = request.getStrStatus().split(",");
                queryWrapper.inSql(FeeItem::getStatus, request.getStrStatus());
            } else {
                queryWrapper.eq(FeeItem::getStatus, request.getStrStatus());
            }
        }
        if (StringUtil.isNotEmpty(request.getItemName())) {
            queryWrapper.like(FeeItem::getItemName, request.getItemName());
        }
        if (request.getFeeItemId() != 0) {
            queryWrapper.eq(FeeItem::getItemId, request.getFeeItemId());
        }
        if (request.getAccountId() != 0) {
            queryWrapper.eq(FeeItem::getAccountId, request.getAccountId());
        }
        if (request.getDeptId() != 0) {
            queryWrapper.eq(FeeItem::getDeptId, request.getDeptId());
        }
        if (request.getPage() == null || request.getSize() == null || request.getPage() == -1 || request.getSize() == -1) {
            request.setPage(1);
            request.setSize(500);
        }
        queryWrapper.orderByDesc(FeeItem::getItemId);


        queryWrapper.notDefaultSelectAll().leftJoin(EntityFeeItemPlan.class,  EntityFeeItemPlan::getComId,FeeItem::getComId)
                .joinAnd(EntityFeeItemPlan::getItemId,FeeItem::getItemId, 0)
                .selectAs((cb) -> {
                    cb.add(" fee_item_plan.tag_id ","tagId",false);
                    cb.add(" fee_item_plan.date_list ","dateList",false);
                    cb.add(" fee_item_plan.day_amount ","dayAmount",false);
                    cb.add(" fee_item_plan.if_leave ","ifLeave",false);
                    cb.add(" fee_item_plan.execution_plan ","executionPlan",false);
                    cb.add(" fee_item_plan.execution_day ","executionDay",false);
                })
                .end();

        Page<FeeItemXMVo> page = new Page<>(request.getPage(), request.getSize());

        Page<FeeItemXMVo>  listFeeItemPage  =  this.joinPage(page,queryWrapper, FeeItemXMVo.class);


        List<Map<String, Object>> mapSumFee = null;
        String itemIds = "";
        if (listFeeItemPage.getTotal() >0l) {
            List<Integer>  ids = listFeeItemPage.getRecords().stream().map(FeeItemXMVo -> FeeItemXMVo.getItemId()).collect(Collectors.toList());
            itemIds = ids.stream()
                    .map(Object::toString) // 将Integer转换为String
                    .collect(Collectors.joining(",")); // 使用逗号和空格连接字符串
        }

        if (!CommonUtil.isNull(itemIds)) {
            mapSumFee = feeDataService.getSumFeeData(request.getComId(), itemIds);
        }
        if (mapSumFee != null && mapSumFee.size() > 0) {
            for (FeeItem item : listFeeItemPage.getRecords()) {
                for (Map<String, Object> map : mapSumFee) {
                    if(item.getItemId() == Integer.parseInt(String.valueOf(map.get("itemId"))) ){
                        item.setPlanAmount(Integer.parseInt(String.valueOf(map.get("planAmount"))));
                        item.setPlanNumber(Integer.parseInt(String.valueOf(map.get("planNumber"))));
                        item.setCompleteAmount(Integer.parseInt(String.valueOf(map.get("completeAmount"))));
                        item.setCompleteNumber(Integer.parseInt(String.valueOf(map.get("completeNumber"))));
                        item.setRefundAmount(Integer.parseInt(String.valueOf(map.get("refundAmount"))));
                        item.setRefundNumber(Integer.parseInt(String.valueOf(map.get("refundNumber"))));
                    }
                }
            }
        }
        return  listFeeItemPage;
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.MASTER)
    public Result newFeeItemXM(Long companyId, FeeItemXMVo request) {
        boolean ret = save(request);
        if (ret) {
            EntityFeeItemPlan entityFeeItemPlan = new EntityFeeItemPlan();
            entityFeeItemPlan.setComId(request.getComId());
            entityFeeItemPlan.setItemId(request.getItemId());
            entityFeeItemPlan.setDateList(request.getDateList());
            entityFeeItemPlan.setTagId(request.getTagId());
            entityFeeItemPlan.setIfLeave(request.getIfLeave());
            entityFeeItemPlan.setDayAmount(request.getDayAmount());
            entityFeeItemPlan.setExecutionPlan(request.getExecutionPlan());
            entityFeeItemPlan.setExecutionDay(request.getExecutionDay());
            feeItemPlanService.addFeeItemPlan(companyId, entityFeeItemPlan);
            return ResultUtil.success();
        }
        return ResultUtil.error(ResultEnum.Err_1);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.MASTER)
    public Result updateFeeItemXM(Long companyId, FeeItemXMVo feeItem) {
        boolean ret = this.updateById(feeItem);
        if (ret) {
            EntityFeeItemPlan entityFeeItemPlan = new EntityFeeItemPlan();
            entityFeeItemPlan.setComId(feeItem.getComId());
            entityFeeItemPlan.setItemId(feeItem.getItemId());
            entityFeeItemPlan.setDateList(feeItem.getDateList());
            entityFeeItemPlan.setTagId(feeItem.getTagId());
            entityFeeItemPlan.setIfLeave(feeItem.getIfLeave());
            entityFeeItemPlan.setDayAmount(feeItem.getDayAmount());
            entityFeeItemPlan.setExecutionPlan(feeItem.getExecutionPlan());
            entityFeeItemPlan.setExecutionDay(feeItem.getExecutionDay());
            feeItemPlanService.editFeeItemPlan(companyId, entityFeeItemPlan);
            return ResultUtil.success();
        }
        return ResultUtil.error(ResultEnum.Err_1);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.SLAVE)
    public List<FeeItemXMVo> getItemListXM(Long companyId) {
        JoinLambdaWrapper<FeeItem> queryWrapper = new JoinLambdaWrapper<>(FeeItem.class);
        queryWrapper.select(FeeItem::getItemId,FeeItem::getComId, FeeItem::getItemName, FeeItem::getAccountId,
                FeeItem::getStatus, FeeItem::getRemark, FeeItem::getDeptId, FeeItem::getCloseTime, FeeItem::getPauseTime, FeeItem::getStartDate,
                FeeItem::getStopDate);
//        queryWrapper.eq(FeeItem::getComId, companyId);

        String date = DateUtils.getDate();

        queryWrapper.ge(FeeItem::getStopDate, date);
        queryWrapper.le(FeeItem::getStartDate, date);
        queryWrapper.eq(FeeItem::getStatus, 2);

        queryWrapper.orderByDesc(FeeItem::getItemId);

        queryWrapper.notDefaultSelectAll().leftJoin(EntityFeeItemPlan.class,  EntityFeeItemPlan::getComId,FeeItem::getComId)
                .joinAnd(EntityFeeItemPlan::getItemId,FeeItem::getItemId, 0)
                //2025-9-30 14:09:53 当天执行的 定时任务 在当天下午3-5点启动
                .eq(EntityFeeItemPlan::getExecutionDay,date)
                .selectAs((cb) -> {
                    cb.add(" fee_item_plan.tag_id ","tagId",false);
                    cb.add(" fee_item_plan.date_list ","dateList",false);
                    cb.add(" fee_item_plan.day_amount ","dayAmount",false);
                    cb.add(" fee_item_plan.if_leave ","ifLeave",false);
                    cb.add(" fee_item_plan.execution_plan ","executionPlan",false);
                    cb.add(" fee_item_plan.execution_day ","executionDay",false);
//                    cb.add(" fee_item_plan.execution_status ","executionStatus",false);
                })
                .end();
        return this.joinList(queryWrapper, FeeItemXMVo.class);
    }

}
